﻿using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Text;
using MethodWorx.Core.DomainModel;
using System.Data.Linq;
using System.Transactions;
using System.Data.SqlClient;

namespace MethodWorx.Core.Linq
{
    public class LinqUnitOfWork : UnitOfWork
    {
        private DataContext context;
        private IRepositoryRegistry repositories;
        private bool inner;
        private TransactionScope transaction;

        public LinqUnitOfWork(DataContext context, IRepositoryRegistry repositories):
           this (context, repositories, false)
        {

        }

        public LinqUnitOfWork(DataContext context, IRepositoryRegistry repositories, bool inner)
        {
            this.inner = inner;
            this.context = context;
            this.repositories = repositories;

            this.transaction = new TransactionScope(TransactionScopeOption.Required,
                                                new TransactionOptions {IsolationLevel = IsolationLevel.ReadUncommitted});
        }

        protected override void OnBegin()
        {
            
            base.OnBegin();
        }

        protected override void OnCommit()
        {
            foreach (AggregateRoot entity in this.inserted.Values)
            {
                this.repositories.GetRepository(entity.GetType()).Insert(entity);
            }

            foreach (AggregateRoot entity in this.updated.Values)
            {
                this.repositories.GetRepository(entity.GetType()).Update(entity);
            }


            foreach (AggregateRoot entity in this.deleted.Values)
            {
                this.repositories.GetRepository(entity.GetType()).Delete(entity);
            }


           // int retryCount = 0;
           // while (retryCount < 3)
           // {
               // try
               // {
                    //using (var ts = new TransactionScope(
                        //TransactionScopeOption.Required,
                        //new TransactionOptions {IsolationLevel = IsolationLevel.ReadUncommitted}))
                    //{
                        this.context.SubmitChanges();
                        //ts.Complete();
                       // break;
                    //}
             //   }
               // catch (SqlException ex)
              //  {
                    //retryCount++;
              //  }
          //  }

            this.transaction.Complete();
            this.transaction.Dispose();
        }

        protected override void OnCancel()
        {
            if (this.IsOpen)
            {
                foreach (AggregateRoot entity in this.updated.Values)
                {
                    //this.context.Refresh(RefreshMode.OverwriteCurrentValues, entity);
                    IRefreshLinqEntity refresh = this.repositories.GetRepository(entity.GetType()) as IRefreshLinqEntity;
                    if (refresh != null)
                        refresh.Refresh(entity);
                }

                this.transaction.Dispose();
                this.transaction = null;
                
            }
        }
    }
}
